#include "directory_operation.h"
int treeDir(userOpInfo_t info, char *indent, char *toPrint) {
	char sql[4096] = {0};
	snprintf(sql, sizeof(sql), "select id,filename,type from file_info where parent_id=%d", info.ID);
	if (mysql_query(info.mysql, sql) != 0) {
		fprintf(stderr, "tree: %s\n", mysql_error(info.mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info.mysql);
	int resNum = mysql_num_rows(res);
	MYSQL_ROW row;

	for (int i = 0; i < resNum; i++) {
		row = mysql_fetch_row(res);
		info.ID = atoi(row[0]); //递归加深度
		//printf("test\n");
		//打印当前行  缩进 + └── + 名字 + 拖尾
		//先确定拖尾
		char tail[10] = {0};
		if (row[2][0] == 'd') {
			strcpy(tail, "/");
		} else {
			memset(tail, 0, sizeof(tail));
		}
		//拼接当前行 并打印
		char connector[4096] = {0};
		snprintf(connector, sizeof(connector), "%s└──%s%s\n", indent, row[1], tail); //设置缩进
		//printf("%s\n",connector);
		//snprintf(toPrint,sizeof(toPrint),"%s\n%s",toPrint,connector);
		//如果当前行是目录,进入递归
		strcat(toPrint, connector);


		if (row[2][0] == 'd') {
			char newIndent[256] = "   ";
			snprintf(newIndent, sizeof(newIndent), "%s%s", indent, "   ");
			treeDir(info, newIndent, toPrint);
		}


	}
	mysql_free_result(res);
	return 1;
}


static int cdll(userOpInfo_t *info, char *toPrintPath) {
	char sql[4096] = {0};
	sprintf(sql, "select * from file_info where id=%d;", info->ID);
	int sqlret = mysql_query(info->mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "1cd.. mysql_query", mysql_error(info->mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info->mysql);
	MYSQL_ROW row = mysql_fetch_row(res);
	mysql_free_result(res);
	if (atoi(row[3]) == -1) { //parentId为-1,已到达根目录,不可再往前
		printf("cd .. 错误!\n");
		return -1;
	} else {
		info->ID = atoi(row[3]);
		char sql1[4096] = {0};
		sprintf(sql1, "select * from file_info where id=%d;", atoi(row[3]));
		sqlret = mysql_query(info->mysql, sql1);
		if (sqlret != 0) {
			fprintf(stderr, "%s:%s\n", "2cd.. mysql_query", mysql_error(info->mysql));
			exit(-1);
		}
		MYSQL_RES *res1 = mysql_store_result(info->mysql);
		MYSQL_ROW row1 = mysql_fetch_row(res1);
		memset(toPrintPath, 0, strlen(toPrintPath));
		strcpy(toPrintPath, row1[6]);
		mysql_free_result(res1);
	}
	return 1;
}

static int cdrr(userOpInfo_t *info, char *toPrintPath) {
	char sql[4096] = {0};
	snprintf(sql, sizeof(sql), "select * from file_info where (filename ='%s' and username ='%s' and parent_id= %d );", info->opName, info->userName, info->ID); //
	int sqlret = mysql_query(info->mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "cdDir mysql_query", mysql_error(info->mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info->mysql);
	int resNum = mysql_num_rows(res);
	if (resNum == 0) {
		printf("cd操作错误: 没有指定路径!\n");
		return -1;
	} else {
		MYSQL_ROW row = mysql_fetch_row(res);
		if (row[5][0] == 'd') {
			info->ID = atoi(row[0]);
			strcpy(toPrintPath, row[6]);
		}

	}
	mysql_free_result(res);
	return 1;
}

int cdDir(userOpInfo_t *info,  char *toPrintPath) {
	//提前存一下当前路径,如果cd失败,还是待在原路径
	int oldPath = info->ID;

	//拆分strtok
	char destDir[1024] = {0};
	strcpy(destDir, info->opName);
	char *p = destDir;
	p = strtok(destDir, "/");
	//printf("p=%s\n",p);
	if (p == NULL) {
		printf("p is NULL\n");
		return -1;
	}
	while (p != NULL) {
		strcpy(info->opName, p);
		if (strcmp(p, "..") == 0) {
			if (cdll(info, toPrintPath) == -1) { //访问根目录之上
				info->ID = oldPath;
				return -1;
			}
		} else if (strcmp(p, ".") == 0) {
			pwdDir(*info, toPrintPath);
		}

		else {
			if (cdrr(info, toPrintPath) == -1) { //当前位置无该目录
				info->ID = oldPath;
				return -1;
			}
		}
		p = strtok(NULL, "/");
	}

	return 1;
}


//传出一个完整的pwd
int pwdDir(userOpInfo_t info, char *toPrintPath) {
	//打印父结点的path
	char sql[4096] = {0};
	sprintf(sql, "select * from file_info where id=%d ;", info.ID);
	int sqlret = mysql_query(info.mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "pwdDir mysql_query", mysql_error(info.mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info.mysql); //得到查询的表
	MYSQL_ROW row = mysql_fetch_row(res);
	strcpy(toPrintPath, row[6]);

	mysql_free_result(res);
	return 1;
}

//传出一个整的字符串  如果是文件夹 加个/
int lsDir(userOpInfo_t info, char *toPrintLs) {
	char sql[4096] = {0};
	sprintf(sql, "select * from file_info where parent_id = %d;", info.ID);

	int sqlret = mysql_query(info.mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "lsDir mysql_query", mysql_error(info.mysql));
		exit(-1);
	}

	MYSQL_RES *res = mysql_store_result(info.mysql);
	int resNum = mysql_num_rows(res);
	if (resNum == 0) {
		mysql_free_result(res);
		return 1;
	}

	char *p = toPrintLs;
	int remaining_space = 4096; // 假设缓冲区足够大，最好使用实际大小

	for (int i = 0; i < resNum; i++) {
		MYSQL_ROW row = mysql_fetch_row(res);
		if (!row[1]) continue; // 确保文件名存在

		int written = 0;
		if (row[5] && row[5][0] == 'd') { // 是目录
			written = snprintf(p, remaining_space, "%s/  ", row[1]);
		} else { // 是文件
			written = snprintf(p, remaining_space, "%s  ", row[1]);
		}

		if (written < 0 || written >= remaining_space) {
			// 缓冲区不足处理
			break;
		}

		p += written;
		remaining_space -= written;
	}

	mysql_free_result(res);
	return 1;
}


int mkDir(userOpInfo_t info) {
	//插入时要把path弄好
	//判断是否已有该目录
	char sql[4096] = {0};
	snprintf(sql, sizeof(sql), "select * from file_info where (filename ='%s' and username ='%s' and parent_id= %d );", info.opName, info.userName, info.ID); //
	int sqlret = mysql_query(info.mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "mkDir1 mysql_query", mysql_error(info.mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info.mysql);
	int resNum = mysql_num_rows(res);
	mysql_free_result(res);//释放上一次
	if (resNum == 0) { //没有该目录,可以创建
		//把要插入的path先拼接好
		char sql1[4096] = {0};
		char path[2048] = {0};
		sprintf(sql1, "select * from file_info where id=%d;", info.ID); //取出当前path
		sqlret = mysql_query(info.mysql, sql1);
		if (sqlret != 0) {
			fprintf(stderr, "%s:%s\n", "mkDir2 mysql_query", mysql_error(info.mysql));
			exit(-1);
		}
		MYSQL_RES *res1 = mysql_store_result(info.mysql);
		MYSQL_ROW row = mysql_fetch_row(res1);
		snprintf(path, sizeof(path), "%s%s/", row[6], info.opName);
		//插入数据库
		char sql2[8192] = {0};
		snprintf(sql2, sizeof(sql2), "insert into file_info (filename,username,parent_id,type,path) values ('%s','%s',%d,'%s','%s');", info.opName, info.userName, info.ID, "d", path);
		sqlret = mysql_query(info.mysql, sql2);
		if (sqlret != 0) {
			fprintf(stderr, "%s:%s\n", "mkDir3 mysql_query", mysql_error(info.mysql));
			exit(-1);
		}
		mysql_free_result(res1);
	} else { //已经有这个名字的目录了
		printf("mkdir操作错误: 已经有此目录了!\n");
		return -1;
	}
	return 1;
}

int rmDir(userOpInfo_t info) {
	char sql[4096] = {0};
	snprintf(sql, sizeof(sql), "select * from file_info where filename ='%s' and username='%s' and parent_id= %d;", info.opName, info.userName, info.ID);
	int sqlret = mysql_query(info.mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "rmDir1 mysql_query", mysql_error(info.mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info.mysql);
	int resNum = mysql_num_rows(res);
	if (resNum == 0) {
		printf("rm操作错误: 没有指定文件夹!\n");
		return -1;
	} else {
		MYSQL_ROW row = mysql_fetch_row(res);
		if (row[5][0] == 'd') {
			char sql1[4096] = {0};
			sprintf(sql1, "delete from file_info where id=%s;", row[0]);
			sqlret = mysql_query(info.mysql, sql1);
			if (sqlret != 0) {
				fprintf(stderr, "%s:%s\n", "rmDir2 mysql_query", mysql_error(info.mysql));
				exit(-1);
			}
		} else {
			printf("rmFile错误: 无法用rmdir删除一个文件!\n");
			return -1;
		}
	}
	mysql_free_result(res);
	return 1;
}

int rmFile(userOpInfo_t info) {
	char sql[4096] = {0};
	snprintf(sql, sizeof(sql), "select * from file_info where filename ='%s' and username='%s' and parent_id= %d;", info.opName, info.userName, info.ID);
	int sqlret = mysql_query(info.mysql, sql);
	if (sqlret != 0) {
		fprintf(stderr, "%s:%s\n", "rmDir1 mysql_query", mysql_error(info.mysql));
		exit(-1);
	}
	MYSQL_RES *res = mysql_store_result(info.mysql);
	int resNum = mysql_num_rows(res);
	if (resNum == 0) {
		printf("rm操作错误: 没有指定文件!\n");
		return -1;
	} else {
		MYSQL_ROW row = mysql_fetch_row(res);
		if (row[5][0] == 'f') {
			//不管quotenum是不是等于1这一行都要删除
			char sql1[4096] = {0};
			sprintf(sql1, "delete from file_info where id=%s;", row[0]);
			sqlret = mysql_query(info.mysql, sql1);
			if (sqlret != 0) {
				fprintf(stderr, "%s:%s\n", "rmDir2 mysql_query", mysql_error(info.mysql));
				exit(-1);
			}
			if (atoi(row[7]) == 1) { //quote等于1顺便删文件
				char filePath[4096] = {0};
				snprintf(filePath, sizeof(filePath), "%s/%s", info.addr, row[4]); //row[4]是哈希值
				remove(filePath);
			}
		} else {
			printf("rmFile错误: 无法用rm删除一个目录!\n");
			return -1;
		}
		if (row[5][0] == 'f' && atoi(row[7]) != 1) {
			//把所有人有这个文件的全部-1
			char sql1[4096] = {0};
			sprintf(sql1, "update file_info set quotenum=quotenum-1 where hash='%s' and type='f';", row[4]); //hash相同的人全-1
			sqlret = mysql_query(info.mysql, sql1);
			if (sqlret != 0) {
				fprintf(stderr, "%s:%s\n", "rmDir2 mysql_query", mysql_error(info.mysql));
				exit(-1);
			}
		}
	}
	mysql_free_result(res);
	return 1;
}

int deleteAccount(userOpInfo_t *userOpInfo) {
	//用户表删除用户修改墓碑值为-1
	userOpInfo_t *useropinfo = userOpInfo;
	char query[4096];
	MYSQL_RES *res;
	MYSQL_ROW row;
	snprintf(query, sizeof(query),
	         "UPDATE user_info SET is_deleted = 1 WHERE username = '%s';", useropinfo->userName);
	if (mysql_query(useropinfo->mysql, query)) {
		fprintf(stderr, "%s\n", mysql_error(useropinfo->mysql));
		return -1;
	}
	//文件表删除用户

	//1删除具体文件
	memset(query, 0, sizeof(query));
	snprintf(query, sizeof(query),
	         "select hash from file_info where username='%s' and type='f' and quotenum=1 ;", useropinfo->userName);
	if (mysql_query(useropinfo->mysql, query)) {
		fprintf(stderr, "%s\n", mysql_error(useropinfo->mysql));
		return -1;
	}
	res = mysql_store_result(useropinfo->mysql);
	for (int i = 0; i < (int)mysql_num_rows(res); i++) {
		row = mysql_fetch_row(res);
		char filePath[4096] = {0};
		snprintf(filePath, sizeof(filePath), "%s/%s", useropinfo->addr, row[0]);
		remove(filePath);
	}
	mysql_free_result(res);

	//2删目标所有文件表内容
	memset(query, 0, sizeof(query));
	snprintf(query, sizeof(query),
	         "SELECT * FROM file_info WHERE username='%s';", useropinfo->userName); //找该用户所有文件
	if (mysql_query(useropinfo->mysql, query)) {
		fprintf(stderr, "%s\n", mysql_error(useropinfo->mysql));
		return -1;
	}
	res = mysql_store_result(useropinfo->mysql);
	for (int i = 0; i < (int)mysql_num_rows(res); i++) {
		row = mysql_fetch_row(res);
		//如果是quote不等于1的文件,把其他所有hash值等于此文件的行-1
		if (row[5][0] == 'f' && atoi(row[7]) != 1) {
			char sql1[4096] = {0};
			sprintf(sql1, "update file_info set quotenum=quotenum-1 where hash='%s' and type='f';", row[4]); //本来写的文件名一样的减1,但应该是hash值一样的减1
			int sqlret = mysql_query(useropinfo->mysql, sql1);
			if (sqlret != 0) {
				fprintf(stderr, "%s:%s\n", " mysql_query", mysql_error(useropinfo->mysql));
				exit(-1);
			}
		}
		//每行都需要删除
		char sql1[4096] = {0};
		sprintf(sql1, "delete from file_info where id=%s;", row[0]);
		int sqlret = mysql_query(useropinfo->mysql, sql1);
		if (sqlret != 0) {
			fprintf(stderr, "%s:%s\n", "mysql_query", mysql_error(useropinfo->mysql));
			exit(-1);
		}

	}

	mysql_free_result(res);

	return 1;
}
